Imports System
Imports System.IO
Imports System.Security.Cryptography

Friend Class JCO
    Public Function GetHash(ByVal sValue As String) As String
        Dim sha As New SHA1CryptoServiceProvider()

        Dim oEncoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding
        Dim oFieldBytes As Byte() = oEncoding.GetBytes(sValue)

        Dim oHashBytes As Byte() = sha.ComputeHash(oFieldBytes)
        Dim sHash As String = oEncoding.GetString(oHashBytes)

        Return sHash
    End Function

    Public Class Crypt
        Private moKey() As Byte = {106, 108, 121, 110, 100, 115, 115, 113, 108, 97, 117, 116, 111, 100, 111, 99}
        Private moIV() As Byte = {106, 108, 105, 111, 110, 46, 105, 110, 99, 99, 114, 121, 112, 116, 111, 100}

        Public Sub New( _
                    ByVal sKey As String, _
                    ByVal bIsEncrypted As Boolean)

            If bIsEncrypted Then
                Dim oKeyValue As New KeyValue("jlion.com")
                Me.Key = oKeyValue.DecryptKey(sKey)
            Else
                Me.Key = sKey
            End If

        End Sub

        Public WriteOnly Property Key() As String
            Set(ByVal value As String)
                If value.Length <> 16 Then
                    Dim oEX As New JCO.Crypt.InvalidKeyException("Key must be 16 characters")
                    Throw oEX
                Else
                    Dim oEncoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding
                    Dim oByteArray As Byte() = oEncoding.GetBytes(value)

                    For i As Byte = 0 To 15
                        moKey(i) = oByteArray(i)
                    Next
                End If
            End Set
        End Property

        Public Function Encrypt(ByVal sUnencryptedMessage As String) As String
            Dim sResult As String = ""

            Try
                Dim oMS As New MemoryStream()

                'Create a new instance of the RijndaelManaged class
                'and encrypt the stream.
                Dim RMCrypto As New RijndaelManaged()

                'Create a CryptoStream, pass it the NetworkStream, and encrypt 
                'it with the Rijndael class.
                Dim CryptStream As New CryptoStream(oMS, RMCrypto.CreateEncryptor(moKey, moIV), CryptoStreamMode.Write)

                'Create a StreamWriter for easy writing to the 
                'network stream.
                Dim SWriter As New StreamWriter(CryptStream)

                'Write to the stream.
                SWriter.Write(sUnencryptedMessage)

                'Close all the connections.
                SWriter.Close()
                CryptStream.Close()

                Dim oByteArray As Byte() = oMS.ToArray()
                sResult = System.Convert.ToBase64String(oByteArray)

                oMS.Close()
            Catch
                'Inform the user that an exception was raised.
                Console.WriteLine("The connection failed.")
            End Try

            Return sResult
        End Function

        Public Function Decrypt(ByVal sEncryptedMessage As String) As String
            'The key and IV must be the same values that were used
            'to encrypt the stream.  
            Dim sResult As String = ""

            Dim oByteArray As Byte() = System.Convert.FromBase64String(sEncryptedMessage)

            Dim oMS As New MemoryStream(oByteArray)

            'Create a new instance of the RijndaelManaged class
            'and decrypt the stream.
            Dim RMCrypto As New RijndaelManaged()

            'Create an instance of the CryptoStream class, pass it the NetworkStream, and decrypt 
            'it with the Rijndael class using the key and IV.
            Dim CryptStream As New CryptoStream(oMS, RMCrypto.CreateDecryptor(moKey, moIV), CryptoStreamMode.Read)

            'Read the stream.
            Dim SReader As New StreamReader(CryptStream)
            sResult = SReader.ReadToEnd()

            'Close the streams.
            SReader.Close()
            oMS.Close()

            Return sResult
        End Function

        Public Class KeyValue
            Private msContainerName As String

            Public Sub New(ByVal sContainerName As String)
                msContainerName = sContainerName
            End Sub

            Public Function EncryptKey(ByVal sUnencryptedKey As String) As String
                ' Create the CspParameters object and set the key container 
                ' name used to store the RSA key pair.
                Dim oEncoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding
                Dim oKey As Byte() = oEncoding.GetBytes(sUnencryptedKey)

                Dim cp As New CspParameters()
                cp.KeyContainerName = msContainerName

                ' Create a new instance of RSACryptoServiceProvider that accesses
                ' the key container MyKeyContainerName.
                Dim rsa As New RSACryptoServiceProvider(cp)
                Dim oEncryptedKey As Byte() = rsa.Encrypt(oKey, True)

                ' Display the key information to the console.
                Return System.Convert.ToBase64String(oEncryptedKey)
            End Function

            Public Function DecryptKey(ByVal sEncryptedKey As String) As String
                ' Create the CspParameters object and set the key container 
                '  name used to store the RSA key pair.
                Dim oKey As Byte() = System.Convert.FromBase64String(sEncryptedKey)

                Dim cp As New CspParameters()
                cp.KeyContainerName = msContainerName

                ' Create a new instance of RSACryptoServiceProvider that accesses
                ' the key container MyKeyContainerName.
                Dim rsa As New RSACryptoServiceProvider(cp)
                Dim oUnencryptedKey As Byte() = rsa.Decrypt(oKey, True)

                ' Display the key information to the console.
                Dim oEncoding As System.Text.ASCIIEncoding = New System.Text.ASCIIEncoding
                Return oEncoding.GetString(oUnencryptedKey)
            End Function
        End Class

        Public Class InvalidKeyException
            Inherits ApplicationException

            Public Sub New()
            End Sub 'New

            Public Sub New(ByVal message As String)
                MyBase.New(message)
            End Sub 'New

            Public Sub New(ByVal message As String, ByVal inner As Exception)
                MyBase.New(message, inner)
            End Sub 'New
        End Class
    End Class
End Class